Skip to content

자유게시판 페이지 구현#72

Merged
jungwon123 merged 6 commits into
mainfrom
feat/boards
Feb 23, 2026
Merged

자유게시판 페이지 구현#72
jungwon123 merged 6 commits into
mainfrom
feat/boards

Conversation

@jungwon123

Copy link
Copy Markdown
Contributor

Summary

자유게시판 페이지 구현

Issue

@jungwon123 jungwon123 added this to the 페이지 milestone Feb 23, 2026
@jungwon123 jungwon123 added the 기능추가 기능개발 및 추가할 때 사용해주세요. label Feb 23, 2026
@github-project-automation github-project-automation Bot moved this to 개발 대기중 in workers Feb 23, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @jungwon123, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 Pull Request는 자유게시판 기능을 웹 애플리케이션에 완벽하게 통합합니다. 사용자는 게시글을 쉽게 생성하고, 인기 게시글을 탐색하며, 검색 및 정렬 옵션을 통해 원하는 정보를 찾을 수 있습니다. 또한, 게시글 상세 페이지에서 좋아요를 누르거나 댓글을 작성하여 다른 사용자와 소통할 수 있습니다. 모든 기능은 React Query를 통해 효율적으로 데이터를 관리하며, 다양한 기기에서 일관된 사용자 경험을 제공하도록 반응형으로 설계되었습니다.

Highlights

  • 자유게시판 페이지 구현: 사용자들이 게시글을 작성, 조회, 수정, 삭제하고 댓글을 달 수 있는 자유게시판 페이지를 새로 구현했습니다.
  • 게시글 목록 및 상세 기능: 베스트 게시글 캐러셀, 전체 게시글 목록, 검색, 정렬(최신순/좋아요순), 무한 스크롤 기능을 포함하며, 각 게시글의 상세 페이지에서는 좋아요, 댓글 작성/수정/삭제 기능을 제공합니다.
  • 게시글 작성 및 수정: 게시글 작성 및 수정 페이지를 통해 사용자가 제목, 내용, 이미지를 첨부하여 게시글을 생성하거나 기존 게시글을 수정할 수 있습니다.
  • React Query를 활용한 데이터 관리: 게시글, 댓글, 사용자 정보 등 모든 데이터 페칭 및 상태 관리에 React Query를 도입하여 캐싱, 재시도, 백그라운드 업데이트 등 고급 기능을 활용하고 코드의 안정성과 성능을 향상시켰습니다.
  • 반응형 디자인 적용: 자유게시판 및 게시글 상세 페이지에 반응형 디자인을 적용하여 데스크톱, 태블릿, 모바일 등 다양한 화면 크기에서 최적화된 사용자 경험을 제공합니다.
  • 사용자 관련 API 및 훅 리팩토링: 기존 shared/apis/user 경로의 사용자 관련 API 및 훅을 mypage/apis로 이동하고, useCurrentUser 훅을 새로 추가하여 전역 사용자 상태 관리를 효율화했습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/app/(root)/boards/BoardsPage.module.css
    • Added styles for the main boards page, including responsive layouts for various sections like header, search, best articles, and article grid.
  • src/app/(root)/boards/BoardsPage.tsx
    • Added the main component for the boards page, implementing best articles carousel, article list, search functionality, sorting options, and infinite scrolling.
  • src/app/(root)/boards/[articleId]/ArticleDetailPage.module.css
    • Added styles for the article detail page, including responsive layouts for the main content, comment section, and floating like button.
  • src/app/(root)/boards/[articleId]/ArticleDetailPage.tsx
    • Added the article detail component, displaying article content, handling like toggles, managing comments (create, edit, delete), and implementing kebab menus for article and comment actions.
  • src/app/(root)/boards/[articleId]/edit/ArticleEditPage.tsx
    • Added the article edit component, allowing users to modify article title, content, and image, with image upload functionality.
  • src/app/(root)/boards/[articleId]/edit/page.tsx
    • Added the page component for article editing, dynamically fetching the article ID from URL parameters.
  • src/app/(root)/boards/[articleId]/page.tsx
    • Added the page component for article details, fetching article and comments data using React Query hooks and displaying current user image.
  • src/app/(root)/boards/apis/article.ts
    • Added API functions for interacting with articles, including fetching lists, getting details, creating, updating, deleting, and managing likes.
  • src/app/(root)/boards/apis/comments.ts
    • Added API functions for interacting with comments, including fetching comments for an article, creating, updating, and deleting comments.
  • src/app/(root)/boards/apis/image.ts
    • Added an API function for uploading images.
  • src/app/(root)/boards/apis/types.ts
    • Added TypeScript interfaces for article and comment data structures, ensuring type safety across the boards feature.
  • src/app/(root)/boards/hooks/useArticles.ts
    • Added React Query hooks for managing article data, including fetching best articles, all articles with infinite scroll, article details, and mutations for create, update, delete, and like actions.
  • src/app/(root)/boards/hooks/useComments.ts
    • Added React Query hooks for managing comment data, including fetching comments for an article and mutations for create, update, and delete actions.
  • src/app/(root)/boards/page.tsx
    • Added the main page component for the boards section, integrating useBestArticles and useArticles hooks to display and manage article data.
  • src/app/(root)/boards/useBreakpoint.ts
    • Added a custom hook to detect the current screen breakpoint (desktop, tablet, mobile) for responsive design logic.
  • src/app/(root)/boards/write/ArticleWritePage.module.css
    • Added styles for the article write page, including responsive adjustments for various screen sizes.
  • src/app/(root)/boards/write/ArticleWritePage.tsx
    • Added the article creation component, allowing users to input title, content, and upload an image, then submit the new article.
  • src/app/(root)/boards/write/page.tsx
    • Added the page component for article creation.
  • src/app/(root)/layout.module.css
    • Updated layout styles to adjust the main content area's margin for the sidebar and improve responsiveness.
  • src/app/(root)/layout.tsx
    • Updated the root layout to include a '자유게시판' (Free Board) button in the sidebar and mobile drawer, and integrated useCurrentUser for dynamic profile display.
  • src/app/(root)/mypage/apis/index.ts
    • Renamed and moved the user API index file from src/shared/apis/user/index.ts.
  • src/app/(root)/mypage/apis/types.ts
    • Renamed and moved the user API types file from src/shared/apis/user/types.ts.
  • src/app/(root)/mypage/apis/userApi.ts
    • Renamed and moved the user API implementation file from src/shared/apis/user/userApi.ts, updated API calls to use a PROXY constant, and adjusted error handling for user deletion to accommodate backend behavior.
  • src/app/(root)/mypage/hooks/useUser.ts
    • Refactored the useUser hook to leverage React Query for fetching and mutating user data, simplifying state management and improving data consistency, and removed direct useEffect for initial data fetching.
  • src/app/(root)/mypage/page.module.css
    • Simplified layout styles for the mypage, removing specific mobile header/sidebar styles and adjusting responsive padding and title sizing.
  • src/app/(root)/mypage/page.tsx
    • Removed direct imports of sidebar and mobile header components, now relying on the root layout for these, and updated profile image handling to use the refactored useUser hook.
  • src/components/Card/ArticleCard/ArticleCard.module.css
    • Updated styles for the ArticleCard component, introducing distinct styling for 'best' articles and making responsive adjustments to image sizes and content layout.
  • src/components/Card/ArticleCard/ArticleCard.tsx
    • Modified the ArticleCard component to support a distinct layout for 'best' articles, including a badge and different content arrangement.
  • src/components/input/styles/CommentInput.module.css
    • Updated comment input styles to ensure consistent appearance when used with or without a profile image.
  • src/components/sidebar/styles/Sidebar.module.css
    • Adjusted sidebar collapsed state styling to maintain position: fixed for overlay behavior.
  • src/hooks/useCurrentUser.ts
    • Added a new useCurrentUser hook using React Query to fetch and manage the current user's data globally, providing a centralized and cached source of user information.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

자유게시판 페이지 구현을 위한 전반적인 구조가 잘 잡혀 있습니다. Next.js App Router와 React Query를 활용하여 효율적인 데이터 관리와 페이지 전환을 구현하셨습니다. 다만, 컴포넌트 내에서 렌더링 도중 상태를 업데이트하는 패턴이나 접근성 측면에서 개선할 수 있는 부분들이 발견되었습니다. 특히 무한 스크롤 구현 시 다음 페이지 파라미터를 계산하는 로직의 안정성을 높이고, 이미지 태그 사용 시 Next.js의 최적화 기능을 활용하도록 권장합니다.

Comment on lines +23 to +28
if (user && user.id !== prevUserId) {
setPrevUserId(user.id);
setName(user.nickname);
setOriginalName(user.nickname);
setProfileImage(user.image);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

컴포넌트 본문 내에서 조건부로 상태를 업데이트(setPrevUserId, setName 등)하는 것은 렌더링 루프를 유발할 위험이 있으며 React의 선언적 프로그래밍 모델에 어긋납니다. user 데이터가 변경될 때 폼을 초기화하려면 useEffect를 사용하는 것이 올바른 방법입니다.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조건이 있어 1회만 실햘되어 렌더링 루프가 발생할 일이 없을겁니다.

Comment on lines +86 to +88
if (safePage !== currentPage) {
setCurrentPage(safePage);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

렌더링 도중에 setCurrentPage를 호출하여 상태를 업데이트하는 것은 React에서 권장되지 않는 패턴입니다. 이는 불필요한 추가 렌더링을 유발할 수 있습니다. safePage를 직접 렌더링 로직에 사용하거나, visibleCount가 변경될 때 useEffect를 통해 업데이트하는 방식이 더 안정적입니다.

width={32}
height={32}
className={styles.searchIcon}
onClick={handleSearchSubmit}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

이미지 태그에 직접 onClick 이벤트를 부여하는 것은 키보드 접근성 측면에서 좋지 않습니다. 검색 버튼 역할을 한다면 button 태그로 감싸고 적절한 aria-label을 제공하는 것이 좋습니다.

            <button type="button" className={styles.searchButton} onClick={handleSearchSubmit} aria-label="검색">
              <Image
                src={searchIcon}
                alt=""
                width={32}
                height={32}
                className={styles.searchIcon}
              />
            </button>

{article.content && <p className={styles.text}>{article.content}</p>}
{article.image && (
<div className={styles.imageWrapper}>
<img src={article.image} alt="" className={styles.articleImage} />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

외부 이미지를 표시할 때도 Next.js의 Image 컴포넌트를 사용하는 것이 이미지 최적화 및 레이아웃 시프트 방지에 유리합니다. 도메인 설정이 필요할 수 있지만, 성능 최적화를 위해 변경을 권장합니다.

Suggested change
<img src={article.image} alt="" className={styles.articleImage} />
<Image src={article.image} alt="" width={200} height={200} className={styles.articleImage} />

getArticles({ page: pageParam, pageSize: PAGE_SIZE, orderBy, keyword: keyword || undefined }),
initialPageParam: 1,
getNextPageParam: (lastPage, allPages) => {
const loaded = allPages.length * PAGE_SIZE;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

현재 로직은 모든 페이지가 정확히 PAGE_SIZE만큼의 아이템을 가지고 있다고 가정합니다. 만약 백엔드에서 예상보다 적은 아이템을 반환하는 예외 상황이 발생하면 다음 페이지 계산이 어긋날 수 있습니다. 실제 로드된 아이템의 총 개수를 기준으로 계산하는 것이 더 안전합니다.

Suggested change
const loaded = allPages.length * PAGE_SIZE;
const loaded = allPages.flatMap((page) => page.list).length;

@yooolleee yooolleee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인 했습니다 고생하셨습니다

@jungwon123 jungwon123 merged commit b0c3a70 into main Feb 23, 2026
1 check passed
@github-project-automation github-project-automation Bot moved this from 개발 대기중 to 개발 완료 in workers Feb 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

기능추가 기능개발 및 추가할 때 사용해주세요.

Projects

Status: 개발 완료

Development

Successfully merging this pull request may close these issues.

자유게시판 페이지 개발

4 participants